home *** CD-ROM | disk | FTP | other *** search
/ Megahits 5 / Megahits 5 (1994)(GTI - Rhein-Main-Soft)(DE)(Disc 2 of 2)[!].iso / archive / conv / iffconvert.lha / IFFConvert / src / iffpack.c < prev    next >
C/C++ Source or Header  |  1993-04-20  |  15KB  |  567 lines

  1. #include <intuition/intuition.h>
  2. #include <proto/intuition.h>
  3. #include <graphics/gfx.h>
  4. #include <graphics/gfxbase.h>
  5. #include <proto/graphics.h>
  6. #include <stdio.h>
  7.  
  8. #include "iffpack.h"
  9.  
  10. #define BADFLAGS (SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO)
  11. #define FLAGMASK (~BADFLAGS)
  12. #define CAMGMASK (FLAGMASK & 0xffffL)
  13.  
  14. #define ID(a,b,c,d) ((((a)<<8|(b))<<8|(c))<<8|(d))
  15.  
  16. void SetRGB32( struct ViewPort *, ULONG, ULONG, ULONG, ULONG );
  17. void GetRGB32( struct ColorMap *, ULONG, ULONG, ULONG *);
  18.  
  19. #pragma libcall GfxBase SetRGB32 354 3210805
  20. #pragma libcall GfxBase GetRGB32 384 910804
  21.  
  22. extern struct GfxBase *GfxBase;
  23.  
  24. struct BMHD {
  25.    ULONG  Size;
  26.    USHORT Width,Height;
  27.    SHORT  LeftEdge,TopEdge;
  28.    UBYTE  Depth;
  29.    UBYTE  Mask;
  30.    UBYTE  Compression;
  31.    UBYTE  Pad;
  32.    USHORT Transparent;
  33.    UBYTE  XAspect,YAspect;
  34.    SHORT  ScrWidth,ScrHeight;
  35. };
  36.  
  37. static int buf[256];
  38. static short count,runlen,ptr;
  39.  
  40. static short rows,bytes,depth;
  41. static cmode;
  42.  
  43. static short TempY=0,TempX=0;
  44. static struct BitMap MyBm;
  45. static struct RastPort MyRast;
  46. static short anzcolors;
  47.  
  48. /* static ULONG colors[256]; */
  49.  
  50. static UBYTE red[256],green[256],blue[256];
  51.  
  52. /* Prototypes */
  53. static ReadHeader(FILE *fp,struct BMHD *bmhd,USHORT *viewmode);
  54. static ReadBMHD(FILE *fp,struct BMHD *bmhd,USHORT *vmode);
  55. static ReadCMAP(FILE *fp);
  56. static ReadCAMG(FILE *fp,USHORT *vmode);
  57. static WriteBMHD(struct Window *w,FILE *fp,short mode);
  58. static WriteCMAP(struct Screen *s,FILE *fp,int);
  59. static WriteCAMG(struct Screen *s,FILE *fp);
  60. static WriteBODY(struct Window *w,FILE *fp,short mode);
  61. static compline(FILE *fp,short bytes,short y,short p);
  62. static comprow(FILE *fp,short rows,short x,short p);
  63. static initcomp(short width,short height,short depth,short mode);
  64. static compget(FILE *fp);
  65.  
  66.  
  67. #define RED(c) (((c)>>16)&0xff)
  68. #define BLUE(c) (((c)>>8)&0xff)
  69. #define GREEN(c) ((c)&0xff)
  70.  
  71.  
  72. #define COLOR32(c) ((c)|((c)<<8)|((c)<<16)|((c)<<24))
  73.  
  74.  
  75. void SetColors(struct ViewPort *vp)
  76. {
  77.    short a;
  78.    if(GfxBase->LibNode.lib_Version<39) {
  79.       for(a=0;a<anzcolors;a++) {
  80.          SetRGB4(vp,a,red[a]>>4,green[a]>>4,blue[a]>>4);
  81.       }
  82.    } else {
  83.       for(a=0;a<anzcolors;a++) {
  84.          SetRGB32(vp,a,COLOR32(red[a]),COLOR32(green[a]),COLOR32(blue[a]));
  85.       }
  86.    }
  87. }
  88. ReadPicSize(FILE *fp,SHORT *winx,SHORT *winy,SHORT *scrx,SHORT *scry,SHORT *depth,USHORT *vmode)
  89. {
  90.    struct BMHD bmhd;
  91.    int err;
  92.    if(err=ReadHeader(fp,&bmhd,vmode)) return(err);
  93.    *winx=bmhd.Width;
  94.    *winy=bmhd.Height;
  95.    *scrx=bmhd.ScrWidth;
  96.    *scry=bmhd.ScrHeight;
  97.    *depth=bmhd.Depth;
  98.    return(0);
  99. }
  100. ReadBody(struct RastPort *rp,FILE *fp)
  101. {
  102.    long size;
  103.    short x,y,p;
  104.    int c;
  105.  
  106.    if(!fread(&size,4,1,fp)) return(BAD_IFF);
  107.  
  108.    if(cmode==0) {
  109.       for(y=0;y<rows;y++) {
  110.          for(p=0;p<depth;p++) {
  111.             for(x=0;x<bytes;x++) {
  112.                if((c=getc(fp))==EOF) return(BAD_IFF);
  113.                MyBm.Planes[p][x]=c;
  114.             }
  115.          }
  116.          ClipBlit(&MyRast,0L,0L,rp,0L,(long)y,(long)TempX,1L,192L);
  117.          WaitBlit();
  118.       }
  119.    } else if(cmode==1) {
  120.       for(y=0;y<rows;y++) {
  121.          for(p=0;p<depth;p++) {
  122.             for(x=0;x<bytes;x++) {
  123.                if((c=compget(fp))==EOF) return(BAD_IFF);
  124.                if(c<256) {
  125.                   MyBm.Planes[p][x]=c;
  126.                }
  127.             }
  128.          }
  129.          ClipBlit(&MyRast,0L,0L,rp,0L,(long)y,(long)TempX,1L,192L);
  130.          WaitBlit();
  131.       }
  132.    } else if(cmode==2) {
  133.       for(x=0;x<bytes;x++) {
  134.          for(p=0;p<depth;p++) {
  135.             for(y=0;y<rows;y++) {
  136.                if((c=compget(fp))==EOF) return(BAD_IFF);
  137.                if(c<256) {
  138.                   MyBm.Planes[p][y<<1]=c;
  139.                }
  140.             }
  141.          }
  142.          ClipBlit(&MyRast,0L,0L,rp,(long)(x<<3),0L,8L,(long)TempY,192L);
  143.          WaitBlit();
  144.       }
  145.    }
  146.    IFFCleanup();
  147.    return(0);
  148. }
  149. WriteWindow(FILE *fp,struct Window *w,int mode,int LastColors)
  150. {
  151.    if(mode<0 || mode>2) return(UNKNOWN_COMPRESSION);
  152.    if(WriteBMHD(w,fp,mode)) return(WRITE_ERROR);
  153.    if(WriteCMAP(w->WScreen,fp,LastColors)) return(WRITE_ERROR);
  154.    if(WriteCAMG(w->WScreen,fp)) return(WRITE_ERROR);
  155.    if(initcomp((short)w->Width,(short)w->Height,(short)w->WScreen->BitMap.Depth,
  156.           mode)) return(NO_MEMORY);
  157.    if(WriteBODY(w,fp,mode)) return(WRITE_ERROR);
  158.    IFFCleanup();
  159.    return(0);
  160. }
  161. void IFFCleanup(void)
  162. {
  163.    short a;
  164.    if(TempX) {
  165.       for(a=0;a<8;a++) {
  166.          if(MyBm.Planes[a])
  167.                  FreeRaster(MyBm.Planes[a],(long)TempX,(long)TempY);
  168.       }
  169.    }
  170.    TempX=TempY=0;
  171. }
  172.  
  173. static ReadHeader(FILE *fp,struct BMHD *bmhd,USHORT *viewmode)
  174. {
  175.    short status=0;
  176.    long id[3],sid,size;
  177.    if(!fread(id,12,1,fp)) return(BAD_IFF);
  178.    if(id[0]!=ID('F','O','R','M')) return(BAD_IFF);
  179.    if(id[2]!=ID('I','L','B','M')) return(BAD_IFF);
  180.    *viewmode=0;
  181.    do {
  182.       if(!fread(&sid,4,1,fp)) return(BAD_IFF);
  183.       if(sid==ID('C','M','A','P')) {
  184.          if(status&1) return(BAD_IFF); /* doppelt */
  185.          if(ReadCMAP(fp)) return(BAD_IFF);
  186.          status|=1;
  187.       } else if(sid==ID('C','A','M','G')) {
  188.          if(status&2) return(BAD_IFF); /* doppelt */
  189.          if(ReadCAMG(fp,viewmode)) return(BAD_IFF);
  190.          status|=2;
  191.       } else if(sid==ID('B','M','H','D')) {
  192.          if(status&4) return(BAD_IFF); /* doppelt */
  193.          if(ReadBMHD(fp,bmhd,viewmode)) return(BAD_IFF);
  194.          status|=4;
  195.       } else if(sid!=ID('B','O','D','Y')) {
  196.          if(!fread(&size,4,1,fp)) return(BAD_IFF);
  197.          size+=size&1;
  198.          if(fseek(fp,size,1)) return(BAD_IFF);
  199.       }
  200.    } while(sid!=ID('B','O','D','Y'));
  201.    if(!(status&1) || !(status&4)) return(BAD_IFF); /* Daten fehlen */
  202.    if(initcomp((short)bmhd->Width,(short)bmhd->Height,(short)bmhd->Depth,
  203.             (short)bmhd->Compression)) return(NO_MEMORY);
  204.    rows=bmhd->Height;
  205.    bytes=((bmhd->Width+15)>>3)&0xfffe;
  206.    depth=bmhd->Depth;
  207.    cmode=bmhd->Compression;
  208.    if(cmode<0 || cmode>2) return(UNKNOWN_COMPRESSION);
  209.    return(0);
  210. }
  211. static ReadBMHD(FILE *fp,struct BMHD *bmhd,USHORT *vmode)
  212. {
  213.    if(!fread(bmhd,sizeof(struct BMHD),1,fp)) return(BAD_IFF);
  214.    if(bmhd->Size!=20) return(BAD_IFF);
  215.    *vmode=0;
  216.    if(bmhd->Width>400 && bmhd->Depth<=4) *vmode|=HIRES;
  217.    if(bmhd->Height>300) *vmode|=LACE;
  218.    if(bmhd->Depth>6) *vmode|=HAM;
  219.    return(0);
  220. }
  221. static ReadCMAP(FILE *fp)
  222. {
  223.    long size;
  224.    short a;
  225.    int r,g,b;
  226.    if(!fread(&size,4,1,fp)) return(1);
  227.    if(size % 3) return(1);
  228.    size/=3;
  229.    if(size>256) return(1);
  230.    anzcolors=size;
  231.    for(a=0;a<size;a++) {
  232.       if((r=getc(fp))==EOF) return(1);
  233.       if((g=getc(fp))==EOF) return(1);
  234.       if((b=getc(fp))==EOF) return(1);
  235.  
  236.       red[a]=r;
  237.       green[a]=g;
  238.       blue[a]=b;
  239.    }
  240.    return(0);
  241. }
  242. static ReadCAMG(FILE *fp,USHORT *vmode)
  243. {
  244.    long a;
  245.    long size;
  246.    if(!fread(&size,4,1,fp)) return(1);
  247.    if(size!=4) return(1);
  248.    if(!fread(&a,4,1,fp)) return(1);
  249.    *vmode=a&CAMGMASK;
  250.    return(0);
  251. }
  252.  
  253. static WriteBMHD(struct Window *w,FILE *fp,short mode)
  254. {
  255.    struct BMHD bm;
  256.    if(!fwrite("FORM    ILBMBMHD",16,1,fp)) return(1);
  257.    bm.Size=20;
  258.    bm.Width=w->Width;
  259.    bm.Height=w->Height;
  260.    bm.ScrWidth=w->WScreen->Width;
  261.    bm.ScrHeight=w->WScreen->Height;
  262.    bm.LeftEdge=bm.TopEdge=0;
  263.    bm.Depth=w->WScreen->BitMap.Depth;
  264.    bm.Mask=bm.Pad=0;
  265.    bm.Compression=mode;
  266.    bm.Transparent=0;
  267.    bm.YAspect=11;
  268.    bm.XAspect=10;
  269.    if((w->WScreen->ViewPort.Modes&LACE) && !(w->WScreen->ViewPort.Modes&HIRES)) bm.XAspect=20;
  270.    if(!(w->WScreen->ViewPort.Modes&LACE) && (w->WScreen->ViewPort.Modes&HIRES)) bm.XAspect=5;
  271.    if(!fwrite(&bm,sizeof(struct BMHD),1,fp)) return(1);
  272.    return(0);
  273. }
  274. static WriteCMAP(struct Screen *s,FILE *fp,int LastColors)
  275. {
  276.    long size;
  277.    short anz,col;
  278.    short i;
  279.    struct ViewPort *vp;
  280.    ULONG ColorSet[3];
  281.  
  282.    vp=&s->ViewPort;
  283.  
  284.    if(!fwrite("CMAP",4,1,fp)) return(1);
  285.    anz=s->BitMap.Depth;
  286.    anz=1<<anz;
  287.  
  288.    if(vp->Modes&HAM) { /* HAM-Screen */
  289.       if(anz<256) anz=16; else anz=64;
  290.    }
  291.  
  292.    if(vp->Modes&EXTRA_HALFBRITE) anz=32;
  293.  
  294.    size=3*anz;
  295.    if(!fwrite(&size,4,1,fp)) return(1);
  296.  
  297.    if(!LastColors || anz>anzcolors) {
  298.       if(GfxBase->LibNode.lib_Version<39) {
  299.  
  300.          for(i=0;i<anz;i++) {
  301.             col=GetRGB4(vp->ColorMap,(long)i);
  302.             red[i]=((col>>8)&0xf)<<4;
  303.             green[i]=((col>>4)&0xf)<<4;
  304.             blue[i]=(col&0xf)<<4;
  305.          }
  306.       } else {
  307.          for(i=0;i<anz;i++) {
  308.             GetRGB32(vp->ColorMap,i,1,ColorSet);
  309.             red[i]=ColorSet[0]>>24;
  310.             green[i]=ColorSet[1]>>24;
  311.             blue[i]=ColorSet[2]>>24;
  312.          }
  313.       }
  314.    }
  315.  
  316.    for(i=0;i<anz;i++) {
  317.       if(putc(red[i],fp)==EOF) return(1);
  318.       if(putc(green[i],fp)==EOF) return(1);
  319.       if(putc(blue[i],fp)==EOF) return(1);
  320.    }
  321.  
  322.    return(0);
  323. }
  324. static WriteCAMG(struct Screen *s,FILE *fp)
  325. {
  326.    long a;
  327.    if(!fwrite("CAMG",4,1,fp)) return(1);
  328.    a=4;
  329.    if(!fwrite(&a,4,1,fp)) return(1);
  330.    a=s->ViewPort.Modes;
  331.    a&=CAMGMASK;
  332.    if(!fwrite(&a,4,1,fp)) return(1);
  333.    return(0);
  334. }
  335. static WriteBODY(struct Window *w,FILE *fp,short mode)
  336. {
  337.    struct RastPort *rp;
  338.    struct BitMap *bm;
  339.    short bytes,rows;
  340.    long pos;
  341.    long size,bodysize,depth;
  342.    short x,y,p;
  343.  
  344.    UBYTE *plane;
  345.  
  346.    rp=w->RPort;
  347.  
  348.    if(!fwrite("BODY    ",8,1,fp)) return(1);
  349.    pos=ftell(fp);
  350.  
  351.    bm=MyRast.BitMap;
  352.  
  353.    bytes=((w->Width+15)>>3) & 0xfffe;
  354.    rows=w->Height;
  355.    depth=bm->Depth;
  356.  
  357.    if(mode==2) {
  358.       for(x=0;x<bytes;x++) {
  359.          if(x) {
  360.             ClipBlit(rp,(x-1L)<<3L,0L,&MyRast,0L,0L,16L,(long)TempY,192L);
  361.             WaitBlit();
  362.          } else {
  363.             ClipBlit(rp,0L,0L,&MyRast,8L,0L,8L,(long)TempY,192L);
  364.             WaitBlit();
  365.          }
  366.          for(p=0;p<depth;p++) {
  367.             if(comprow(fp,rows,x,p)) return(1);
  368.          }
  369.       }
  370.    } else if(mode==1) {
  371.       for(y=0;y<rows;y++) {
  372.          if(y) {
  373.             ClipBlit(rp,0L,(long)y-1L,&MyRast,0L,0L,(long)TempX,2L,192L);
  374.             WaitBlit();
  375.          } else {
  376.             ClipBlit(rp,0L,0L,&MyRast,0L,1L,(long)TempX,1L,192L);
  377.             WaitBlit();
  378.          }
  379.          for(p=0;p<depth;p++) {
  380.             if(compline(fp,bytes,y,p)) return(1);
  381.          }
  382.       }
  383.    } else {
  384.       for(y=0;y<rows;y++) {
  385.          ClipBlit(rp,0L,(long)y,&MyRast,0L,0L,(long)TempX,1L,192L);
  386.          WaitBlit();
  387.          for(p=0;p<depth;p++) {
  388.             plane=MyBm.Planes[p];
  389.             for(x=0;x<bytes;x++) {
  390.                if(putc((int)(plane[x]),fp)==EOF) return(1);
  391.             }
  392.          }
  393.       }
  394.    }
  395.  
  396.    size=ftell(fp);
  397.    if(size&1) if(putc(0,fp)==EOF) return(1); /* auf Wortgrenze auffuellen */
  398.    bodysize=size-pos;
  399.    if(fseek(fp,pos-4L,0)) return(1);
  400.    if(!fwrite(&bodysize,4,1,fp)) return(1);
  401.    if(fseek(fp,4L,0)) return(1);
  402.    size=(size-8+1)&0xfffffffe;
  403.    if(!fwrite(&size,4,1,fp)) return(1);
  404.    return(0);
  405. }
  406.  
  407. static compline(FILE *fp,short bytes,short y,short p)
  408. {
  409.    short x,x2,lx;
  410.    short found;
  411.    short a;
  412.    UBYTE * ptr;
  413.  
  414.    ptr=&MyBm.Planes[p][bytes];
  415.    lx=0;
  416.    for(x=0;x<bytes;x++) {
  417.       x2=x;
  418.       found=0;
  419.       while(ptr[x2]==ptr[x2+1] && x2<bytes-1 && x2-x<127) x2++;
  420.       x2++;
  421.       if((x-lx)==0 && x2-x>=2 || x2-x>=3) {
  422.          if(x-lx) {
  423.             if(putc((int)(x-lx-1),fp)==EOF) return(1);
  424.             for(a=lx;a<x;a++) if(putc((int)ptr[a],fp)==EOF) return(1);
  425.          }
  426.          if(putc(x-x2+1,fp)==EOF) return(1);
  427.          if(putc((int)ptr[x],fp)==EOF) return(1);
  428.          x=x2-1;
  429.          found=1;
  430.       }
  431.       if(found) {
  432.          lx=x+1;
  433.       } else {
  434.          if(x-lx==127) {
  435.             if(fputc(127,fp)==EOF) return(1);
  436.             for(a=lx;a<=x;a++) if(putc(ptr[a],fp)==EOF) return(1);
  437.             lx=x+1;
  438.          }
  439.       }
  440.    }
  441.    if(lx<bytes) {
  442.       if(putc(bytes-lx-1,fp)==EOF) return(1);
  443.       for(a=lx;a<bytes;a++) if(putc((int)ptr[a],fp)==EOF) return(1);
  444.    }
  445.    return(0);
  446. }
  447. static comprow(FILE *fp,short rows,short x,short p)
  448. {
  449.    short y,y2,y3,ly;
  450.    short found;
  451.    short a;
  452.    UBYTE * ptr;
  453.  
  454.    ptr=MyBm.Planes[p];
  455.    ly=0;
  456.    for(y=0;y<rows;y++) {
  457.       y3=y2=y;
  458.       found=0;
  459.       while(ptr[(y2<<1)+1]==ptr[(y2<<1)+3] && y2<rows-1 &&
  460.                                                     y2-y<127) y2++;
  461.       y2++;
  462.       if(x) {
  463.          while(ptr[y3<<1]==ptr[(y3<<1)+1] && y3<rows &&
  464.                                                     y3-y<256) y3++;
  465.       }
  466.       if(y2>=y3) {
  467.          if(y-ly==0 && y2-y>=2 || y2-y>=3) {
  468.             if(y-ly) {
  469.                if(putc(y-ly-1,fp)==EOF) return(1);
  470.                for(a=ly;a<y;a++)
  471.                   if(putc((int)ptr[(a<<1)+1],fp)==EOF) return(1);
  472.             }
  473.             if(putc(y-y2+1,fp)==EOF) return(1);
  474.             if(putc((int)ptr[(y<<1)+1],fp)==EOF) return(1);
  475.             y=y2-1;
  476.             found=1;
  477.          }
  478.       } else {
  479.          if(!y-ly && y3-y>=2 || y3-y>=3) {
  480.             if(y-ly) {
  481.                if(putc(y-ly-1,fp)==EOF) return(1);
  482.                for(a=ly;a<y;a++)
  483.                   if(putc((int)ptr[(a<<1)+1],fp)==EOF) return(1);
  484.             }
  485.             if(putc(128,fp)==EOF) return(1);
  486.             if(putc(y3-y-1,fp)==EOF) return(1);
  487.             y=y3-1;
  488.             found=1;
  489.          }
  490.       }
  491.       if(found) {
  492.          ly=y+1;
  493.       } else {
  494.          if(y-ly==127) {
  495.             if(fputc(127,fp)==EOF) return(1);
  496.             for(a=ly;a<=y;a++)
  497.                   if(putc(ptr[(a<<1)+1],fp)==EOF) return(1);
  498.             ly=y+1;
  499.          }
  500.       }
  501.    }
  502.    if(ly<rows) {
  503.       if(putc(rows-ly-1,fp)==EOF) return(1);
  504.       for(a=ly;a<rows;a++)
  505.          if(putc((int)ptr[(a<<1)+1],fp)==EOF) return(1);
  506.    }
  507.    return(0);
  508. }
  509.  
  510. static initcomp(short width,short height,short depth,short mode)
  511. {
  512.    short a;
  513.    if(TempX) IFFCleanup();
  514.    if(mode!=2) {
  515.       TempX=width;
  516.       TempY=2;
  517.       InitRastPort(&MyRast);
  518.       InitBitMap(&MyBm,(long)depth,(long)width,2L);
  519.       for(a=0;a<8;a++) MyBm.Planes[a]=0;
  520.       for(a=0;a<depth;a++) {
  521.          if(!(MyBm.Planes[a]=AllocRaster((long)width,2L))) return(NO_MEMORY);
  522.       }
  523.    } else {
  524.       TempX=16;
  525.       TempY=height;
  526.       InitRastPort(&MyRast);
  527.       InitBitMap(&MyBm,(long)depth,16L,(long)height);
  528.       for(a=0;a<8;a++) MyBm.Planes[a]=0;
  529.       for(a=0;a<depth;a++) {
  530.          if(!(MyBm.Planes[a]=AllocRaster(16L,(long)height))) return(NO_MEMORY);
  531.       }
  532.    }
  533.    MyRast.BitMap=&MyBm;
  534.    count=ptr=0;
  535.    runlen=1;
  536.    return(0);
  537. }
  538.  
  539. static compget(FILE *fp)
  540. {
  541.    int c;
  542.    char cc;
  543.    UBYTE val;
  544.    if(ptr>=count) {
  545.       if((c=getc(fp))==EOF) return(EOF);
  546.       cc=c;
  547.       ptr=0;
  548.       if(c==128) {
  549.          if((c=getc(fp))==EOF) return(EOF);
  550.          count=c+1;
  551.          for(c=0;c<count;c++) buf[c]=256;
  552.       } else if(cc>=0) {
  553.          count=cc+1;
  554.          for(c=0;c<count;c++) if((buf[c]=getc(fp))==EOF) return(EOF);
  555.       } else {
  556.          count=-cc+1;
  557.          if((c=getc(fp))==EOF) return(EOF);
  558.          val=c;
  559.          for(c=0;c<count;c++) buf[c]=val;
  560.       }
  561.    }
  562.    if(ptr>=count) return(EOF);
  563.    return(buf[ptr++]);
  564. }
  565.  
  566.  
  567.